package com.hengpeng.itfin.domain.partner.chinapnr;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.google.gson.JsonSyntaxException;
import com.hengpeng.common.util.ObjectHelper;
import com.hengpeng.common.util.StringHelper;
import com.hengpeng.common.util.WebClientUtil;
import com.hengpeng.itfin.domain.partner.chinapnr.util.KeyTool;
import com.hengpeng.itfin.tools.JsonUtils;
import com.hengpeng.itfinbase.message.partner.AddBidInfoResponse;
import com.hengpeng.itfinbase.message.partner.CorpOpenResponseMsg;
import com.hengpeng.itfinbase.message.partner.QueryAcctsResponseMsg;
import com.hengpeng.itfinbase.message.partner.TransferRequest;

public class Test
{
	String url = "http://mertest.chinapnr.com/muser/publicRequests";

	String publicKey = "393939393939000000000000000000000000000030303031F60CB7B659222AEB12654EBB05C43CC2408154D57EED62D8F46FB946815A631D4A708DBA667673F69A279E371CA16064296643CBB0785E18FFDA84DB065DCA42D48349D3839B6723B604AC0BF19994147E56C6EFFD7BF6CF37E766D58E6CC6EF023B2A03E00D85829C51550012B1ABBF5710D6D9BED03A69BEC144D73EE2154F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000133D851D515306218";

	String privateKey = "38383030303100000000000000000000000000003030303031303234303031333937353132303138BF45E645B551CA21FCAF6A7D1B45F93BE13663EED76AAD05073BD2DDE883EBB1CD498CA339A1F3E351C5F423F07272D024AF314C24C843E1BCBB645ED4879EFE84BCB8D4A27B12AB2B61A16A1D2E6F910A05CB31C6056068717B41BAA723335F90C46D0B5642205D28A750E898EC7389D457977A3A739A4B329B504A0612DD1525D5EACCC91892A70FCDDF6CBD4231B7A124C898E42B839120451DE4C1C9216E13CAABC2142228D26A8AA79879C9994802D54FFA62EF3114793FA1FB915BB901392A8503FEBEC931AD99F03A7FB871519F21E3F47BFBF867C02F3147E2044449CAF5DFB40FA4E76CAE30658F95A2E953D08C9B149F9643A2309CBE44CE05D2080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010001FBCD29F4DF4A2B4AA2FD46E447E46615918CBE3395888B2A35CAB8186659AF75321344BD438D222957A0B0C0F1115C9C2C822445F3E3F7F041DC015BB6C41F211F1584177F913792E99EA0888D177B1F592F7E547C16A08399CD21F8A1FE4D85A6843BAA3F4ACA006D4CEBF77B7A211974D303B012A7D7BF2E3FA12FAFC9B2B8FB298D1C835CBF079C8D59B06A9CEF5D2B2AA5F9121182D841257ADE10472E8BD061CAF5758B7247028F496D2B959398BD10DB968469B2CE45E90C8789CBE09B978B6C2CE8E1BEAA895FAF505F64CB71F0DD26B22412FC31B08B59D7D6625C55B1CDCD1433F98E26F6F680C4D6DC6F226A430113AD8E2F1EC7F0033BF1F2C63466F2005F2C68202F10F1E7D4498C259F65D6A2761B1FCD0FF883B851B3059B02D911BA3980E0393978D85424A915C4F9D2522DD326BA25BABFC46CB8C8D6F1F31B9E3BBC9E43B853";

	KeyTool keyTool = new KeyTool(privateKey, publicKey);

	public static void main(String[] args) throws Exception
	{
		Test t = new Test();
		t.testUsrUnFreeze();
	}

	public void testQueryAccts()
	{
		String resultJsonString = "{'CmdId':'QueryAccts','RespCode':'000','RespDesc':'成功','ChkValue':'9A218101376A6EC9576D8E5E583F6021079A0F286A002CFA379010E5E6A0342D9C5FE0FC606817A2F98B903C21CEE6EC782723EAB8AECF004E883768420D04D8C3B5A058FE1D9F0848B78A8F720C983220730290BF4AB887E28BE314D826CC52255283246A95695873BA158B7BD919BA782CCAA8D0ABBEB92FAA57278EBAC8F1','Version':null,'MerCustId':'6000060000002526','AcctDetails':[{'AcctType':'BASEDT','SubAcctId':'BASEDT','AvlBal':'0.00','AcctBal':'0.00','FrzBal':'0.00'},{'AcctType':'MERDT','SubAcctId':'MDT000001','AvlBal':'988867.15','AcctBal':'988867.15','FrzBal':'0.00'},{'AcctType':'MERDT','SubAcctId':'MDT000003','AvlBal':'1010206.52','AcctBal':'1010206.52','FrzBal':'0.00'},{'AcctType':'MERDT','SubAcctId':'MDT000004','AvlBal':'1000110.00','AcctBal':'1000110.00','FrzBal':'0.00'},{'AcctType':'SPEDT','SubAcctId':'SDT000001','AvlBal':'999899.98','AcctBal':'999899.98','FrzBal':'0.00'}],'PlaintStr':'QueryAccts0006000060000002526'}";
		QueryAcctsResponseMsg obj = (JsonUtils.createGson().create().fromJson(resultJsonString,
				QueryAcctsResponseMsg.class));

		System.out.println(obj);
	}

	public void testPackageTransferRequest()
	{
		String version ="10";
		String RetUrl="http://15889458695.xicp.net:59480/pgNotify.htm";
		String BgRetUrl="http://15889458695.xicp.net:59480/bgNotify.htm";
		String money="10.00";
		TransferRequest re=new TransferRequest();
		re.setCmdId("Transfer");
		re.setOrdId("10000000000003");
		re.setOutCustId("6000060000002526");
		re.setOutAcctId("MDT000001");
		re.setInCustId("6000060001592138");
		re.setMerCustId("6000060000002526");
		
		// Version +CmdId + OrdId + OutCustId + OutAcctId + TransAmt+ InCustId+ InAcctId+ RetUrl + BgRetUrl+ MerPriv
		StringLinker sl = new StringLinker();
		sl.append(version).append(re.getCmdId()).append(re.getOrdId())
				.append(re.getOutCustId()).append(re.getOutAcctId()).append(money)
				.append(re.getInCustId()).append(RetUrl)
				.append(BgRetUrl);
		String checkValue = keyTool.signMessage(sl.toString());// 签名

		ParamHash pl=new ParamHash();
		pl.append("Version", version).append("CmdId", re.getCmdId())
				.append("OrdId",re.getOrdId()).append("ChkValue", checkValue)
				.append("OutCustId",re.getOutCustId()).append("OutAcctId",re.getOutAcctId())
				.append("TransAmt",money).append("InCustId", re.getInCustId())
				.append("RetUrl", RetUrl)
				.append("BgRetUrl",BgRetUrl);

		String htmlString = WebClientUtil.autoSubmitHtmlForm("utf-8", "转账", url,
				pl.getParams(), "POST");
		System.out.print("生成的表单内容为：\n" + htmlString);
	}

	public void testCorpRegisterQuery()
	{
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("Version", "10"));
		params.add(new BasicNameValuePair("CmdId", "CorpRegisterQuery"));
		params.add(new BasicNameValuePair("MerCustId", "6000060000002526"));
		params.add(new BasicNameValuePair("BusiCode", "rt44444444444444"));

		// Version+CmdId+MerCustId+BusiCode +ReqExt
		StringLinker sl = new StringLinker();
		sl.append("10").append("CorpRegisterQuery").append("6000060000002526").append("rt44444444444444");

		String checkValue = keyTool.signMessage(sl.toString());// 签名

		params.add(new BasicNameValuePair("ChkValue", checkValue));

		try
		{
			System.out.println(URLDecoder.decode(httpRequest(params, url), "utf-8"));
		}
		catch (UnsupportedEncodingException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void testCropOpen()
	{
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("Version", "10"));
		params.add(new BasicNameValuePair("CmdId", "CorpRegister"));
		params.add(new BasicNameValuePair("MerCustId", "6000060000002526"));
		params.add(new BasicNameValuePair("UsrId", "100000"));
		params.add(new BasicNameValuePair("UsrName", "深圳市恒鹏科技开发有限公司"));
		params.add(new BasicNameValuePair("InstuCode", "100000000"));
		params.add(new BasicNameValuePair("BusiCode", "1000"));
		params.add(new BasicNameValuePair("TaxCode", "1000"));
		params.add(new BasicNameValuePair("CharSet", "utf-8"));
		params.add(new BasicNameValuePair("GuarType", "N"));
		params.add(new BasicNameValuePair("BgRetUrl", "http://15889458695.xicp.net:59480/openPgNotify.htm"));

		StringLinker sl = new StringLinker();
		sl.append("10").append("CorpRegister").append("6000060000002526").append("100000").append("深圳市恒鹏科技开发有限公司")
				.append("100000000").append("1000").append("1000").append("N")
				.append("http://15889458695.xicp.net:59480/openPgNotify.htm");

		String checkValue = keyTool.signMessage(sl.toString());// 签名

		params.add(new BasicNameValuePair("ChkValue", checkValue));
		CorpOpenResponseMsg msg = JsonUtils.createGson().create()
				.fromJson(httpRequest(params, url), CorpOpenResponseMsg.class);
		System.out.println(msg);
	}

	/**
	 * <pre>
	 * 创建标的
	 * </pre>
	 * @throws Exception
	 * @throws JsonSyntaxException
	 */
	public void testAddBorrowInfo() throws JsonSyntaxException, Exception
	{
		String rtKey = "CmdId+RespCode+MerCustId+ProId+BorrCustId+BorrTotAmt+GuarCompId+GuarAmt+ProArea+BgRetUrl+MerPriv+RespExt";
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("Version", "10"));
		params.add(new BasicNameValuePair("CmdId", "AddBidInfo"));
		params.add(new BasicNameValuePair("MerCustId", "6000060000002526"));
		params.add(new BasicNameValuePair("ProId", "102"));
		params.add(new BasicNameValuePair("BorrCustId", "6000060000002526"));
		params.add(new BasicNameValuePair("BorrTotAmt", "10000.00"));
		params.add(new BasicNameValuePair("YearRate", "10.12"));
		params.add(new BasicNameValuePair("RetType", "01"));
		params.add(new BasicNameValuePair("BidStartDate", "20150602130500"));
		params.add(new BasicNameValuePair("BidEndDate", "20150603130500"));
		params.add(new BasicNameValuePair("RetAmt", "11000.00"));
		params.add(new BasicNameValuePair("RetDate", "20160603"));
		// params.add(new BasicNameValuePair("GuarCompId", "6000060000002526"));
		// params.add(new BasicNameValuePair("GuarAmt", "100.12"));
		params.add(new BasicNameValuePair("ProArea", "4402"));
		params.add(new BasicNameValuePair("BgRetUrl", "http://15889458695.xicp.net:59480/itfints/openPgNotify.htm"));
		Map<String, String> map = new HashMap<String, String>();
		for (NameValuePair nameValuePair : params)
		{
			map.put(nameValuePair.getName(), nameValuePair.getValue());
		}
		String str = "Version+CmdId+MerCustId+ProId+BorrCustId+BorrTotAmt+YearRate+RetType+BidStartDate+BidEndDate+RetAmt+RetDate+GuarCompId+GuarAmt+ProArea+BgRetUrl+MerPriv+ReqExt";
		StringLinker sl = new StringLinker();
		String[] array = str.split("\\+");
		for (int i = 0; i < array.length; i++)
		{
			sl.append(map.get(array[i]));
		}

		String checkValue = keyTool.signMessage(sl.toString());// 签名

		params.add(new BasicNameValuePair("ChkValue", checkValue));
		String rtstring = httpRequest(params, url);
		if (!StringHelper.isEmpty(rtstring))
		{
			Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(rtstring, HashMap.class);
			if (verifySign(paramMap, rtKey.split("\\+")))
			{
				System.out.println(ObjectHelper.toPropertiesString(JsonUtils.createGson().create()
						.fromJson(rtstring, AddBidInfoResponse.class)));
			}
		}
	}

	public void testTendCancle() throws JsonSyntaxException, Exception
	{
		String key = "Version+CmdId+MerCustId+OrdId+OrdDate+TransAmt+UsrCustId+IsUnFreeze+UnFreezeOrdId+FreezeTrxId+RetUrl+BgRetUrl+MerPriv+ReqExt";
		String rtKey = "CmdId+RespCode+MerCustId+OrdId+OrdDate+TransAmt+UsrCustId+IsUnFreeze+UnFreezeOrdId+FreezeTrxId+RetUrl+BgRetUrl+MerPriv+RespExt";
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("Version", "10"));
		params.add(new BasicNameValuePair("CmdId", "TenderCancle"));
		params.add(new BasicNameValuePair("MerCustId", "6000060000002526"));
		params.add(new BasicNameValuePair("OrdId", "1000546456001"));
		params.add(new BasicNameValuePair("OrdDate", "20150609"));
		params.add(new BasicNameValuePair("TransAmt", "4000.00"));
		params.add(new BasicNameValuePair("UsrCustId", "6000060001494002"));
		// params.add(new BasicNameValuePair("IsUnFreeze", "Y"));
		// params.add(new BasicNameValuePair("UnFreezeOrdId", "1000546456001"));
		params.add(new BasicNameValuePair("MerPriv", "1"));
		params.add(new BasicNameValuePair("BgRetUrl", "http://szhelper.gicp.ne:17981/bgNotify.htm"));
		addChkValue(params, key.split("\\+"));
		String rtstring = httpRequest(params, url);
		if (!StringHelper.isEmpty(rtstring))
		{
			rtstring = URLDecoder.decode(rtstring, "UTF-8");
			Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(rtstring, HashMap.class);
			if (verifySign(paramMap, rtKey.split("\\+")))
			{
				System.out.println(rtstring);
			}
			else
			{
				System.out.println("投资编号:987670,进行标的放款时,请求响应加密摘要验证不匹配");
			}
		}
	}

	public void testloan() throws JsonSyntaxException, Exception
	{
		String key = "Version+CmdId+MerCustId+OrdId+OrdDate+OutCustId+TransAmt+Fee+SubOrdId+SubOrdDate+InCustId+DivDetails+FeeObjFlag+IsDefault+IsUnFreeze+UnFreezeOrdId+FreezeTrxId+BgRetUrl+MerPriv+ReqExt";
		String rtKey = "CmdId+RespCode+MerCustId+OrdId+OrdDate+OutCustId+OutAcctId+TransAmt+Fee+InCustId+InAcctId+SubOrdId+SubOrdDate+FeeObjFlag+IsDefault+IsUnFreeze+UnFreezeOrdId+FreezeTrxId+BgRetUrl+MerPriv+RespExt";
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("Version", "20"));
		params.add(new BasicNameValuePair("CmdId", "Loans"));
		params.add(new BasicNameValuePair("MerCustId", "6000060000002526"));
		params.add(new BasicNameValuePair("OrdId", "10987670"));
		params.add(new BasicNameValuePair("OrdDate", "20150609"));
		params.add(new BasicNameValuePair("OutCustId", "6000060001494002"));

		params.add(new BasicNameValuePair("TransAmt", "4000.00"));
		params.add(new BasicNameValuePair("Fee", "0.00"));
		params.add(new BasicNameValuePair("SubOrdId", "987670"));
		params.add(new BasicNameValuePair("SubOrdDate", "20150609"));
		params.add(new BasicNameValuePair("InCustId", "6000060001488153"));
		params.add(new BasicNameValuePair(
				"DivDetails",
				"[{\"DivCustId\":\"6000060000002526\",\"DivAcctId\":\"SDT000001\",\"DivAmt\":\"0.40\"},{\"DivCustId\":\"6000060001493940\",\"DivAcctId\":\"MDT000001\",\"DivAmt\":\"0.80\"}]"));
		params.add(new BasicNameValuePair("FeeObjFlag", "O"));
		params.add(new BasicNameValuePair("IsDefault", "N"));
		params.add(new BasicNameValuePair("IsUnFreeze", "N"));
		params.add(new BasicNameValuePair("FreezeTrxId", "201506091234567890"));
		params.add(new BasicNameValuePair("UnFreezeOrdId", "987670"));
		params.add(new BasicNameValuePair("BgRetUrl", "http://szhelper.gicp.ne:17981/bgNotify.htm"));
		addChkValue(params, key.split("\\+"));
		String rtstring = httpRequest(params, url);
		if (!StringHelper.isEmpty(rtstring))
		{
			rtstring = URLDecoder.decode(rtstring, "UTF-8");
			Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(rtstring, HashMap.class);
			if (verifySign(paramMap, rtKey.split("\\+")))
			{
				System.out.println(rtstring);
			}
			else
			{
				System.out.println("投资编号:987670,进行标的放款时,请求响应加密摘要验证不匹配");
			}
		}
	}

	public void testUsrUnFreeze() throws JsonSyntaxException, Exception
	{
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("Version", "10"));
		params.add(new BasicNameValuePair("CmdId", "UsrUnFreeze"));
		params.add(new BasicNameValuePair("MerCustId", "6000060000002526"));
		params.add(new BasicNameValuePair("OrdId", "987685"));
		params.add(new BasicNameValuePair("OrdDate", "20150610"));
		params.add(new BasicNameValuePair("TrxId", "201506100000755724"));
		params.add(new BasicNameValuePair("BgRetUrl", "http://szhelper.gicp.ne:17981/bgNotify.htm"));
		addChkValue(params, SignKey.UsrUnFreeze.getRequestKey());
		String rtstring = httpRequest(params, url);
		if (!StringHelper.isEmpty(rtstring))
		{
			rtstring = URLDecoder.decode(rtstring, "UTF-8");
			Map<String, String> paramMap = JsonUtils.createGson().create().fromJson(rtstring, HashMap.class);
			if (verifySign(paramMap, SignKey.UsrUnFreeze.getResponseKey()))
			{
				System.out.println(rtstring);
			}
			else
			{
				System.out.println("投资编号:987670,进行标的放款时,请求响应加密摘要验证不匹配");
			}
		}
	}

	public void addChkValue(List<NameValuePair> params, String[] keys)
	{
		Map<String, String> map = new HashMap<String, String>();
		for (NameValuePair nameValuePair : params)
		{
			if (!StringHelper.isEmpty(nameValuePair.getValue()))
			{
				map.put(nameValuePair.getName(), nameValuePair.getValue());
			}
		}
		StringLinker sl = new StringLinker();
		for (String key : keys)
		{
			String value = map.get(key);
			if (!StringHelper.isEmpty(value))
			{
				sl.append(value);
			}
		}
		String checkValue = keyTool.signMessage(sl.toString());// 签名
		params.add(new BasicNameValuePair("ChkValue", checkValue));
	}

	public boolean verifySign(Map<String, String> param, String[] verifyList) throws Exception
	{
		if (param.isEmpty() || verifyList == null)
			return false;

		String plaintStr = "";
		for (String i : verifyList)
		{
			String value = param.get(i);
			if (!StringHelper.isEmpty(value))
			{
				plaintStr += URLDecoder.decode(value, "UTF-8");
			}
		}
		return keyTool.verifySign(plaintStr, (String) param.get("ChkValue"));
	}

	public class StringLinker
	{
		private StringBuffer buffer = new StringBuffer();

		public StringLinker append(String str)
		{
			if (str != null)
				buffer.append(str.trim());
			return this;
		}

		public String toString()
		{
			return this.buffer.toString();
		}
	}

	public String httpRequest(List<NameValuePair> params, String url)
	{
		String respStr = "";
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try
		{
			HttpPost post = new HttpPost(url);
			post.setEntity(new UrlEncodedFormEntity(params, "utf-8"));

			HttpResponse response = httpclient.execute(post);
			HttpEntity entity = response.getEntity();
			respStr = EntityUtils.toString(entity);
			EntityUtils.consume(entity);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				httpclient.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
		return respStr;
	}

	private class ParamHash
	{
		private HashMap<String, String> params = new HashMap<String, String>();

		public ParamHash append(String key, String value)
		{
			if (key != null && value != null)
				params.put(key, value);

			return this;
		}

		public HashMap<String, String> getParams()
		{
			return this.params;
		}
	}
}
